home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- ** **
- ** Module: SR_Marker.c **
- ** **
- ** **
- ** Purpose: This is the entry point into the renderer for markers. **
- ** **
- ** **
- ** **
- ** Copyright (C) 1996 Apple Computer, Inc. All rights reserved. **
- ** **
- ** **
- *****************************************************************************/
- #include <assert.h>
- #include <stdlib.h>
-
- #include "QD3D.h"
- #include "QD3DMath.h"
- #include "QD3DStyle.h"
- #include "QD3DSet.h"
- #include "QD3DView.h"
-
- #include "SR.h"
- #include "SR_Marker.h"
-
-
- /*===========================================================================*\
- *
- * Routine : SR_Geometry_Marker()
- *
- * Comment : This function is the marker renderer entry point, it
- * collects the state of escher, updates the state of the world
- * and then calls the appropiate rendering function.
- *
- \*===========================================================================*/
-
- TQ3Status SR_Geometry_Marker(
- TQ3ViewObject view,
- TSRPrivate *srPrivate,
- TQ3GeometryObject marker,
- const TQ3MarkerData *markerData)
- {
- TQ3ColorRGB color;
- TQ3Boolean highlightState;
- TQ3XClipMaskState clipMaskState;
-
- UNUSED(marker);
-
- assert(view != NULL);
- assert(srPrivate != NULL);
- assert(markerData != NULL);
-
- /*
- * Call the application's idle progress method, via the view. If
- * the app's method returns kQ3Failure, then we don't go on.
- */
- if (SR_IdleProgress(view, srPrivate) == kQ3Failure) {
- return (kQ3Success);
- }
-
- if (srPrivate->drawRegion == NULL) {
- return (kQ3Success);
- }
-
- /*
- * Find out if we're clipped out or not. No reason to go any
- * further if the region is obscured or entirely off-screen.
- */
- Q3XDrawRegion_GetClipFlags(srPrivate->drawRegion, &clipMaskState);
- if (clipMaskState == kQ3XClipMaskNotExposed) {
- return (kQ3Success);
- }
-
- /*
- * Lazy-evaluate the various transforms for the pipeline
- */
- if (SR_UpdatePipeline(srPrivate) == kQ3Failure) {
- return (kQ3Failure);
- }
-
- /*
- * Highlight state and color are from the view, unless
- * overridden by the markerAttributeSet
- */
- highlightState = srPrivate->viewHighlightState;
- color = srPrivate->viewDiffuseColor;
-
- /*
- * Check if we have a marker attribute set.
- * If so, then see if we can get a color and highlight state
- * out of it.
- */
- if (markerData->markerAttributeSet != NULL) {
- TQ3XAttributeMask attributeMask;
-
- attributeMask = Q3XAttributeSet_GetMask(markerData->markerAttributeSet);
-
- if (attributeMask & kQ3XAttributeMaskDiffuseColor) {
- Q3AttributeSet_Get(
- markerData->markerAttributeSet,
- kQ3AttributeTypeDiffuseColor,
- &color);
- }
-
- if (attributeMask & kQ3XAttributeMaskHighlightState) {
- Q3AttributeSet_Get(
- markerData->markerAttributeSet,
- kQ3AttributeTypeHighlightState,
- &highlightState);
- }
- }
-
- /*
- * If we're highlighting, then see if we can get a highlight color
- * out of the view's attribute set. Use that as the color, if it's there.
- */
- if (highlightState == kQ3True &&
- (srPrivate->viewHighlightAttributeSet != NULL)) {
- TQ3XAttributeMask attributeMask;
-
- attributeMask = Q3XAttributeSet_GetMask(srPrivate->viewHighlightAttributeSet);
-
- if (attributeMask & kQ3XAttributeMaskDiffuseColor) {
- Q3AttributeSet_Get(
- srPrivate->viewHighlightAttributeSet,
- kQ3AttributeTypeDiffuseColor,
- &color);
- }
- }
-
- {
- TQ3Matrix4x4 *localToDC;
- TQ3RationalPoint4D *deviceVertices = NULL;
- TQ3RationalPoint4D *renderVertices = NULL;
- MarkerFunction2D markerFunc;
- TSRMarkerRasterData rasterMarker;
- TQ3Point2D saveDeviceVertices;
-
- /*
- * 1.0 transform local coordinate vertices to DC
- * 1.5 add in offsets
- * 2.0 clip in DC
- * 3.0 paste bitmap
- */
- TQ3Bitmap *bitmapPtr = (TQ3Bitmap *)&(markerData->bitmap);
- float inverseW;
-
- localToDC = &srPrivate->transforms.localToDC;
-
- deviceVertices = malloc(sizeof(TQ3RationalPoint4D));
- if (deviceVertices == NULL) {
- return (kQ3Failure);
- }
-
- /* 1. transform LC to DC */
- Q3Point3D_To4DTransformArray(
- &markerData->location,
- localToDC,
- deviceVertices,
- 1,
- sizeof(TQ3Point3D),
- sizeof(TQ3RationalPoint4D));
-
- inverseW = 1.0 / deviceVertices->w;
- deviceVertices->x *= inverseW;
- deviceVertices->y *= inverseW;
- deviceVertices->z *= inverseW;
-
- deviceVertices->x += markerData->xOffset;
- deviceVertices->y += markerData->yOffset;
-
- deviceVertices->x = FLOAT_ROUND_TO_LONG_POSITIVE(deviceVertices->x);
- deviceVertices->y = FLOAT_ROUND_TO_LONG_POSITIVE(deviceVertices->y);
-
- /* Check for trivial rejection clipping */
-
- if (deviceVertices->z < srPrivate->clipPlanesInDC[4] ||
- deviceVertices->z > srPrivate->clipPlanesInDC[5] ||
- deviceVertices->x + bitmapPtr->width - 1 < srPrivate->clipPlanesInDC[0] ||
- deviceVertices->x > srPrivate->clipPlanesInDC[1] ||
- deviceVertices->y + bitmapPtr->height - 1 < srPrivate->clipPlanesInDC[2] ||
- deviceVertices->y > srPrivate->clipPlanesInDC[3] ) {
- /*
- * trivial rejection
- */
- return (kQ3Success);
- }
-
- /*
- * Marker dimensions could be bigger than window so clip
- * against all boundaries
- */
- rasterMarker.bitmap = bitmapPtr;
-
- rasterMarker.startRowSkip = 0;
- rasterMarker.endRowSkip = 0;
-
- saveDeviceVertices.x = deviceVertices->x;
- saveDeviceVertices.y = deviceVertices->y;
-
- if (deviceVertices->x < srPrivate->clipPlanesInDC[0]) {
- rasterMarker.startRowSkip =
- srPrivate->clipPlanesInDC[0] - deviceVertices->x;
- deviceVertices->x = srPrivate->clipPlanesInDC[0];
- }
-
- if (saveDeviceVertices.x + bitmapPtr->width - 1 >
- srPrivate->clipPlanesInDC[1]) {
- rasterMarker.endRowSkip =
- saveDeviceVertices.x + bitmapPtr->width - 1
- - srPrivate->clipPlanesInDC[1];
- }
-
- rasterMarker.startLineSkip = 0;
- rasterMarker.endLineSkip = 0;
-
- if (deviceVertices->y < srPrivate->clipPlanesInDC[2]) {
- rasterMarker.startLineSkip =
- srPrivate->clipPlanesInDC[2] - deviceVertices->y;
- deviceVertices->y = srPrivate->clipPlanesInDC[2];
- }
-
- if (saveDeviceVertices.y + bitmapPtr->height - 1 >
- srPrivate->clipPlanesInDC[3]) {
- rasterMarker.endLineSkip =
- saveDeviceVertices.y + bitmapPtr->height - 1
- - srPrivate->clipPlanesInDC[3];
- }
-
- /*
- * Call the appropriate marker rasterization function
- */
- markerFunc = ((TSRRasterFunctions *)
- (srPrivate->currentRasterFunctions))->markerFunction;
- if ((*markerFunc)(
- srPrivate,
- (TQ3Point3D *)deviceVertices,
- &rasterMarker,
- &color) == kQ3Failure) {
- if (deviceVertices != NULL) {
- free(deviceVertices);
- return (kQ3Failure);
- }
- }
-
- if (deviceVertices != NULL) {
- free(deviceVertices);
- }
- }
-
-
- return (kQ3Success);
- }
-